using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;
using System.Linq;
using TMPro;
using UnityEngine.SceneManagement;

public class MapUIManager : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
{
    [Header("UI引用")]
    public RectTransform mapContainer;
    public RectTransform mapBackground;
    public Transform nodesContainer;
    public Transform connectionsContainer;
    public Image playerMarker;
    public GameObject nodePrefab;
    public LineRenderer connectionPrefab;

    [Header("地图配置")]
    public MapManager mapManager;
    public float dragSensitivity = 0.5f;

    // 节点类型颜色配置
    [Header("节点颜色")]
    public Color learningColor = Color.blue;
    public Color challengeColor = Color.red;
    public Color marketColor = Color.green;
    public Color dormitoryColor = Color.yellow;
    public Color eventColor = Color.magenta;
    public Color bossColor = Color.black;

    [Header("布局设置")]
    public float horizontalRange = 1000f;
    public float verticalRange = 400f;
    public bool centerNodes = true;

    private Dictionary<NodeType, Color> nodeColors;
    private Dictionary<string, GameObject> nodeGameObjects = new Dictionary<string, GameObject>();
    private Dictionary<string, List<GameObject>> connectionLines = new Dictionary<string, List<GameObject>>(); // 统一使用 GameObject
    private Vector2 dragStartPosition;
    private Vector2 containerStartPosition;
    private bool isDragging = false;
    private int maxDragX = 400;
    private int minDragX = -400;
    private int maxDragY = 200;
    private int minDragY = -200;

    // 添加缺失的 currentMap 变量
    private MapData currentMap;

    // ConnectionInfo 辅助类
    public class ConnectionInfo : MonoBehaviour
    {
        public string fromNodeId;
        public string toNodeId;
    }

    private void Awake()
    {
        // 初始化颜色字典
        nodeColors = new Dictionary<NodeType, Color>
        {
            { NodeType.Learning, learningColor },
            { NodeType.ChallengeTeacher, challengeColor },
            { NodeType.Market, marketColor },
            { NodeType.Dormitory, dormitoryColor },
            { NodeType.Event, eventColor },
            { NodeType.Boss, bossColor }
        };

        if (mapManager == null)
            mapManager = FindObjectOfType<MapManager>();
    }

    private void Start()
    {
        // 检查所有必要引用
        if (nodePrefab == null) Debug.LogError("NodePrefab not assigned!");
        if (connectionPrefab == null) Debug.LogError("ConnectionPrefab not assigned!");
        if (mapManager == null) Debug.LogError("MapManager not assigned!");
        if (nodesContainer == null) Debug.LogError("NodesContainer not assigned!");
        if (connectionsContainer == null) Debug.LogError("ConnectionsContainer not assigned!");
        if (playerMarker == null) Debug.LogError("PlayerMarker not assigned!");

        // 确保背景不可拖动
        if (mapBackground != null)
        {
            Image bgImage = mapBackground.GetComponent<Image>();
            if (bgImage != null) bgImage.raycastTarget = true;
        }

        // 订阅事件
        if (mapManager != null)
        {
            mapManager.OnMapChanged += OnMapChanged;
            Debug.Log("Subscribed to OnMapChanged event");
        }

        // 初始绘制
        if (mapManager != null && mapManager.GetCurrentMapData() != null)
        {
            Debug.Log("Drawing initial map");
            DrawMap(mapManager.GetCurrentMapData());
            // 初始设置节点交互状态
            UpdateNodeInteractability();
        }
        else
        {
            Debug.Log("No initial map data available");
        }
    }

    private void OnDestroy()
    {
        // 取消订阅事件
        if (mapManager != null)
            mapManager.OnMapChanged -= OnMapChanged;
    }

    /// <summary>
    /// 当地图变化时重新绘制
    /// </summary>
    private void OnMapChanged(MapData newMap)
    {
        currentMap = newMap;  // 现在这个变量已经声明了
        ClearMap();
        DrawMap(newMap);
    }

    /// <summary>
    /// 绘制整个地图
    /// </summary>
    private void DrawMap(MapData mapData)
    {
        currentMap = mapData;

        // 创建所有节点
        foreach (var nodePair in mapData.nodes)
        {
            CreateNodeGameObject(nodePair.Value);
        }

        // 创建所有连接
        foreach (var nodePair in mapData.nodes)
        {
            CreateNodeConnections(nodePair.Value);
        }

        // 调试节点位置
        DebugAllNodePositions();

        // 更新玩家位置
        UpdatePlayerPosition();

        // 更新节点交互状态
        UpdateNodeInteractability();
    }

    /// <summary>
    /// 创建节点游戏对象
    /// </summary>
    private void CreateNodeGameObject(MapNode node)
    {
        // 检查预制体是否为空
        if (nodePrefab == null)
        {
            Debug.LogError("NodePrefab is null! Please assign in inspector.");
            return;
        }

        // 检查容器是否为空
        if (nodesContainer == null)
        {
            Debug.LogError("NodesContainer is null! Please assign in inspector.");
            return;
        }

        GameObject nodeObj = Instantiate(nodePrefab, nodesContainer);
        if (nodeObj == null)
        {
            Debug.LogError("Failed to instantiate node prefab!");
            return;
        }

        nodeObj.name = $"Node_{node.nodeId}";
        Debug.Log($"Node_{node.nodeId}已创建");

        // 设置位置
        RectTransform rectTransform = nodeObj.GetComponent<RectTransform>();
        if (rectTransform == null)
        {
            Debug.LogError("Node prefab missing RectTransform component!");
            return;
        }

        float posX = node.position.x * horizontalRange;
        float posY = node.position.y * verticalRange + 300f;

        if (centerNodes)
        {
            posX -= horizontalRange / 2;
            posY -= verticalRange / 2;
        }

        rectTransform.anchoredPosition = new Vector2(posX, posY);

        Debug.Log($"Node {node.nodeName} positioned at ({posX}, {posY}) from normalized ({node.position.x}, {node.position.y})");

        // 设置节点外观
        Image nodeImage = nodeObj.GetComponent<Image>();
        if (nodeImage != null && nodeColors.ContainsKey(node.nodeType))
        {
            nodeImage.color = nodeColors[node.nodeType];
        }

        // 设置节点文本
        TextMeshProUGUI nodeText = nodeObj.GetComponentInChildren<TextMeshProUGUI>();
        if (nodeText != null)
        {
            nodeText.text = node.nodeName;
        }

        // 添加点击事件
        Button nodeButton = nodeObj.GetComponentInChildren<Button>();
        if (nodeButton != null)
        {
            string cid = node.nodeId;
            nodeButton.onClick.AddListener(() => OnNodeClicked(cid));
            // 初始设置为不可交互
            nodeButton.interactable = false;
        }
        else
        {
            Debug.LogError($"No Button component found on node prefab: {node.nodeId}");
        }

            // 存储引用
            nodeGameObjects[node.nodeId] = nodeObj;
    }

    /// <summary>
    /// 创建节点连接线
    /// </summary>
    private void CreateNodeConnections(MapNode node)
    {
        if (!connectionLines.ContainsKey(node.nodeId))
            connectionLines[node.nodeId] = new List<GameObject>();

        Debug.Log($"Creating connections for node: {node.nodeId}, Neighbors: {node.neighborIds.Count}");

        foreach (string neighborId in node.neighborIds)
        {
            MapNode neighbor = currentMap.GetNode(neighborId);
            if (neighbor != null)
            {
                Debug.Log($"Connecting {node.nodeId} -> {neighborId}");
                CreateConnectionLine(node, neighbor);
            }
            else
            {
                Debug.LogWarning($"Neighbor node not found: {neighborId}");
            }
        }
    }

    /// <summary>
    /// 创建连接线
    /// </summary>
    private void CreateConnectionLine(MapNode fromNode, MapNode toNode)
    {
        GameObject lineObj = new GameObject($"Connection_{fromNode.nodeId}_to_{toNode.nodeId}");
        lineObj.transform.SetParent(connectionsContainer);
        lineObj.transform.SetAsFirstSibling();

        // 添加 Image 组件
        Image lineImage = lineObj.AddComponent<Image>();
        RectTransform rect = lineObj.GetComponent<RectTransform>();

        // 获取节点的 anchoredPosition（UI 坐标）
        Vector2 startPos = GetNodeAnchoredPosition(fromNode);
        Vector2 endPos = GetNodeAnchoredPosition(toNode);

        // 计算线的方向、长度和角度
        Vector2 direction = endPos - startPos;
        float distance = direction.magnitude;
        float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;

        // 设置 RectTransform
        rect.pivot = new Vector2(0, 0.5f);
        rect.anchorMin = new Vector2(0, 0.5f);
        rect.anchorMax = new Vector2(0, 0.5f);
        rect.sizeDelta = new Vector2(distance, 3f); // 宽度=距离，高度=线粗
        rect.anchoredPosition = startPos;
        rect.localRotation = Quaternion.Euler(0, 0, angle);

        // 设置颜色
        bool isReachable = IsNodeReachable(toNode.nodeId);
        lineImage.color = isReachable ? Color.white : new Color(0.5f, 0.5f, 0.5f, 0.7f);

        // 存储连接信息
        ConnectionInfo connInfo = lineObj.AddComponent<ConnectionInfo>();
        connInfo.fromNodeId = fromNode.nodeId;
        connInfo.toNodeId = toNode.nodeId;

        // 存储引用
        connectionLines[fromNode.nodeId].Add(lineObj);

        Debug.Log($"UI Connection created from {fromNode.nodeId} to {toNode.nodeId}, length: {distance}");
    }


    /// <summary>
    /// 获取节点的 UI 坐标（anchoredPosition）
    /// </summary>
    private Vector2 GetNodeAnchoredPosition(MapNode node)
    {
        if (nodeGameObjects.ContainsKey(node.nodeId))
        {
            RectTransform rectTransform = nodeGameObjects[node.nodeId].GetComponent<RectTransform>();
            Vector2 pos = rectTransform.anchoredPosition;
            return new Vector2(pos.x + 1000f, pos.y); // 反向抵消偏移
        }
        return Vector2.zero;
    }

    

    /// <summary>
    /// 节点点击事件
    /// </summary>
    private void OnNodeClicked(string nodeId)
    {
        Debug.Log("按钮正在被点击");
        if (!isDragging && IsNodeReachable(nodeId))
        {
            mapManager.MoveToNode(nodeId);

            // 等待一帧后更新UI（确保数据已更新）
            StartCoroutine(UpdateUIAfterMove()); ;

            MapNode clickedNode = currentMap.GetNode(nodeId);
            if (clickedNode != null)
            {
                SwitchSceneByNodeType(clickedNode);
            }
        }
    }

    // <summary>
    /// 移动后更新UI的协程
    /// </summary>
    private System.Collections.IEnumerator UpdateUIAfterMove()
    {
        yield return null; // 等待一帧，确保MapManager已更新数据

        UpdatePlayerPosition();
        UpdateNodeInteractability();

        Debug.Log("UI更新完成");
    }

    /// <summary>
    /// 根据节点类型切换到不同场景
    /// </summary>
    private void SwitchSceneByNodeType(MapNode node)
    {
        switch (node.nodeType)
        {
            case NodeType.Learning:
            case NodeType.ChallengeTeacher:
            case NodeType.Boss:
                SceneManager.LoadScene("SampleScene"); // 战斗场景
                break;

            case NodeType.Market:
                //SceneManager.LoadScene("BattleTestScene"); // 商店场景
                break;

            case NodeType.Dormitory:
                //SceneManager.LoadScene("BattleTestScene"); // 宿舍场景
                break;

            case NodeType.Event:
                //SceneManager.LoadScene("BattleTestScene"); // 事件场景
                break;

            default:
                //SceneManager.LoadScene("Scene2"); // 默认跳转到Scene2
                break;
        }
    }

    /// <summary>
    /// 检查节点是否可到达
    /// </summary>
    private bool IsNodeReachable(string nodeId)
    {
        if (mapManager == null) return false;

        List<MapNode> reachableNodes = mapManager.GetReachableNodes();
        return reachableNodes.Any(node => node.nodeId == nodeId);
    }

    /// <summary>
    /// 更新玩家位置标记
    /// </summary>
    private void UpdatePlayerPosition()
    {
        if (mapManager == null || playerMarker == null)
        {
            Debug.LogError("MapManager or PlayerMarker is null!");
            return;
        }

        Debug.Log("正在更新玩家位置");

        string currentNodeId = mapManager.GetCurrentNodeId();
        Debug.Log($"当前节点ID: {currentNodeId}");

        if (string.IsNullOrEmpty(currentNodeId))
        {
            Debug.LogWarning("当前节点ID为空！");
            return;
        }

        if (!nodeGameObjects.ContainsKey(currentNodeId))
        {
            Debug.LogError($"节点 {currentNodeId} 不存在于 nodeGameObjects 字典中！");
            Debug.Log($"可用的节点: {string.Join(", ", nodeGameObjects.Keys)}");
            return;
        }

        GameObject currentNodeObj = nodeGameObjects[currentNodeId];
        if (currentNodeObj == null)
        {
            Debug.LogError($"节点对象 {currentNodeId} 为null！");
            return;
        }

        RectTransform nodeRect = currentNodeObj.GetComponent<RectTransform>();
        if (nodeRect == null)
        {
            Debug.LogError($"节点 {currentNodeId} 没有RectTransform组件！");
            return;
        }

        // 获取节点的世界坐标
        Vector3 nodeWorldPosition = nodeRect.position;
        Debug.Log($"节点 {currentNodeId} 的世界坐标: {nodeWorldPosition}");

        Vector3 adjustedPosition = new Vector3(
            nodeWorldPosition.x,
            nodeWorldPosition.y + 40f,
            nodeWorldPosition.z
            );
        // 设置玩家标记位置
        playerMarker.transform.position = adjustedPosition;
        
        playerMarker.gameObject.SetActive(true);

        Debug.Log($"玩家位置已更新到节点: {currentNodeId}, 位置: {nodeWorldPosition}");
    }

    /// <summary>
    /// 添加调试信息来检查所有节点位置
    /// </summary>
    private void DebugAllNodePositions()
    {
        Debug.Log("=== 所有节点位置信息 ===");
        foreach (var nodePair in nodeGameObjects)
        {
            if (nodePair.Value != null)
            {
                RectTransform rect = nodePair.Value.GetComponent<RectTransform>();
                if (rect != null)
                {
                    Debug.Log($"节点 {nodePair.Key}: anchoredPosition={rect.anchoredPosition}, position={rect.position}, localPosition={rect.localPosition}");
                }
            }
        }
    }

    /// <summary>
    /// 更新节点交互状态
    /// </summary>
    private void UpdateNodeInteractability()
    {
        if (mapManager == null) return;

        // 获取当前节点和可达节点
        string currentNodeId = mapManager.GetCurrentNodeId();
        List<MapNode> reachableNodes = mapManager.GetReachableNodes();
        HashSet<string> reachableNodeIds = new HashSet<string>(reachableNodes.Select(n => n.nodeId));

        Debug.Log("开始重置节点状态");
        int i = 0;
        // 重置所有节点状态
        foreach (var nodePair in nodeGameObjects)
        {
            Button button = nodePair.Value.GetComponentInChildren<Button>();
            Image image = nodePair.Value.GetComponentInChildren<Image>();

            if (button == null)
            {
                Debug.Log("无法找到button");
                continue;
            }

            bool isReachable = reachableNodeIds.Contains(nodePair.Key);
            bool isCurrent = nodePair.Key == currentNodeId;
            bool isVisited = currentMap.GetNode(nodePair.Key).isVisited;

            // 设置交互状态：只有可达且不是当前节点的节点可交互
            button.interactable = isReachable && !isCurrent;
            //Debug.Log($"{i++}号节点状态已更新，当前状态为{button.interactable}");
            // 设置透明度
            Color color = image.color;
            color.a = isReachable ? 1f : (isVisited ? 0.9f : 0.9f);
            image.color = color;
        }

        // 更新连线颜色
        UpdateConnectionColors();
    }

    /// <summary>
    /// 更新连线颜色
    /// </summary>
    private void UpdateConnectionColors()
    {
        if (mapManager == null) return;

        HashSet<string> reachableNodeIds = new HashSet<string>(
            mapManager.GetReachableNodes().Select(n => n.nodeId)
        );

        foreach (var linePair in connectionLines)
        {
            foreach (GameObject lineObj in linePair.Value)
            {
                if (lineObj == null) continue;

                Image lineImage = lineObj.GetComponent<Image>();
                if (lineImage == null) continue;

                // 获取连接信息
                ConnectionInfo connInfo = lineObj.GetComponent<ConnectionInfo>();
                bool isReachable = false;

                if (connInfo != null)
                {
                    // 精确判断：目标节点是否可达
                    isReachable = reachableNodeIds.Contains(connInfo.toNodeId);
                }

                lineImage.color = isReachable ? Color.gray : Color.gray;
            }
        }
    }

    /// <summary>
    /// 清除地图
    /// </summary>
    private void ClearMap()
    {
        // 清除节点
        foreach (var nodePair in nodeGameObjects)
        {
            if (nodePair.Value != null)
                Destroy(nodePair.Value);
        }
        nodeGameObjects.Clear();

        // 清除连线
        foreach (var lineList in connectionLines.Values)
        {
            foreach (GameObject line in lineList)
            {
                if (line != null)
                    Destroy(line);
            }
        }
        connectionLines.Clear();
    }

    // 拖动接口实现
    public void OnBeginDrag(PointerEventData eventData)
    {
        isDragging = true;
        dragStartPosition = eventData.position;
        containerStartPosition = mapContainer.anchoredPosition;
    }

    public void OnDrag(PointerEventData eventData)
    {
        Vector2 dragDelta = (eventData.position - dragStartPosition) * dragSensitivity;
        Vector2 newPosition = containerStartPosition + dragDelta;

        // 限制拖动边界
        newPosition.x = Mathf.Clamp(newPosition.x, minDragX, maxDragX);
        newPosition.y = Mathf.Clamp(newPosition.y, minDragY, maxDragY);

        mapContainer.anchoredPosition = newPosition;
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        isDragging = false;
    }

    /// <summary>
    /// 重置地图位置
    /// </summary>
    public void ResetMapPosition()
    {
        if (mapContainer != null)
            mapContainer.anchoredPosition = Vector2.zero;
    }

    /// <summary>
    /// 聚焦到玩家当前位置
    /// </summary>
    public void FocusOnPlayer()
    {
        if (mapManager == null) return;

        string currentNodeId = mapManager.GetCurrentNodeId();
        if (nodeGameObjects.ContainsKey(currentNodeId))
        {
            RectTransform nodeRect = nodeGameObjects[currentNodeId].GetComponent<RectTransform>();
            Vector2 targetPosition = -nodeRect.anchoredPosition;

            mapContainer.anchoredPosition = targetPosition;
        }
    }
}